#ifndef INPUT_H_
#define INPUT_H_

/************************************************************************/
/*  Input class: Based on implementation by Ben Martin                  */
/************************************************************************/
// Now supports mouse input, does not leak memory, and the mouse buttons don't get stuck on!
#define DIRECTINPUT_VERSION (0x0800)

#include <windows.h>
#include <d3dx9.h>
#include "dinput.h"

#include "assert.h"

#include <string>

/* Simplified version of Bens input class, uses only keyboard*/
class Input
{
private:
    Input();
    Input(const Input& other){}
    Input& operator=(const Input& other){}
    ~Input(){}
public:

    /* singleton get function */
    static Input* Instance()
    {
        static Input* i = NULL;
        if( i == NULL)
        {
            i = new Input;
        }
        return i;
    }

    /* Tidying up memory */
    static void Kill(){delete Instance();}

    bool Init();
    void Process();

    typedef enum KeyState
    {
        KeyState_NotPressed=0,
        KeyState_Pressed,
        KeyState_Held,
        KeyState_Released,
        KeyState_MaxKeyStates
    }KeyState;

    class InputDevice
    {
    public:
        InputDevice();
        virtual ~InputDevice(){Shutdown();}
        virtual bool Init() = 0;
        virtual void Process (void) = 0;
        virtual void Shutdown(void);
        bool Process(void *pData, int DataSize);
        KeyState GetKey(int KeyID) const;
        int GetKeyCount()	const;

    protected:
        void AllocateKeys(int NoOfKeys);
        void UpdateKey(bool bPressed, KeyState *pKey);
        LPDIRECTINPUTDEVICE8	m_DeviceHandle; 
        int			m_KeyCount;
        KeyState* m_pProcessedKeys;		

    };

    class Keyboard : public InputDevice
    {
    public:

        Keyboard();
        virtual bool Init();
        virtual void Process();
    };

    const Keyboard &GetKeyboard();

    LPDIRECTINPUT8	GetDInput()
    {
        return 	mDirectInput; 
    }

    class Mouse : public InputDevice
    {
    public:
        Mouse();
        bool Init();
        void Process();
        const D3DXVECTOR2 &GetPosition(void) const{return m_position;}		
        const D3DXVECTOR2 &GetOldPosition(void) const{return m_oldPosition;}

        typedef enum Key{Key_Left = 0
            ,Key_Middle = 2
            ,Key_Right = 1
        };

    private:

        D3DXVECTOR2 m_position;
        D3DXVECTOR2 m_oldPosition;
    };

    const Mouse &GetMouse();
private:

    LPDIRECTINPUT8	mDirectInput; 
    Keyboard		mKeyboard;
    Mouse           mMouse;
    

};
#endif